package cn.com.acca.ma.dao.impl;

import cn.com.acca.ma.dao.ModelTopStockDao;
import cn.com.acca.ma.dao.ModelTopStockDetailDao;
import cn.com.acca.ma.hibernate.util.HibernateUtil;
import cn.com.acca.ma.jpa.util.JpaUtil;
import cn.com.acca.ma.model.ModelTopStock;
import cn.com.acca.ma.model.ModelTopStockDetail;
import java.util.Date;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;

import javax.persistence.EntityManager;

public class ModelTopStockDetailDaoImpl extends BaseDaoImpl<ModelTopStockDetailDaoImpl> implements
    ModelTopStockDetailDao {

    /**
     * 按照日期，向表MDL_TOP_STOCK_DETAIL中写入数据
     * @param multithreading
     * @param beginDate
     * @param endDate
     */
    @Override
    public void writeModelTopStockDetailByDate(boolean multithreading, String beginDate, String endDate) {
        logger.info("按照日期【" + beginDate + "】和【" + endDate + "】，向表MDL_TOP_STOCK_DETAIL中写入数据");

        Session newSession = null;
        SQLQuery query;
        if (multithreading) {
            newSession = HibernateUtil.newSession();
            newSession.beginTransaction();
            query = newSession.createSQLQuery("{call PKG_MODEL_RECORD.WRITE_MDL_TOP_STOCK_DETAIL(?, ?)}");
        } else {
            session = HibernateUtil.currentSession();
            session.beginTransaction();
            query = session.createSQLQuery("{call PKG_MODEL_RECORD.WRITE_MDL_TOP_STOCK_DETAIL(?, ?)}");
        }

        query.setParameter(0, beginDate);
        query.setParameter(1, endDate);
        query.executeUpdate();

        if (multithreading) {
            newSession.getTransaction().commit();
            HibernateUtil.closeNewSessionFactory(newSession);
        } else {
            session.getTransaction().commit();
            session.close();
        }

        logger.info("方法writeModelTopStockDetail执行完毕");
    }

    /**
     * 根据开始日期beginDate和结束日期endDate计算表MDL_TOP_STOCK_DETAIL中的percentage_*_ma*字段
     * @param beginDate
     * @param endDate
     */
    @Override
    public void writeModelTopStockDetailMAByDate(String beginDate, String endDate) {
        logger.info("按照日期【" + beginDate + "】和【" + endDate
            + "】，计算表MDL_TOP_STOCK_DETAIL中的percentage_*_ma*字段");

        session = HibernateUtil.currentSession();
        session.beginTransaction();
        SQLQuery query = session
            .createSQLQuery("{call PKG_MODEL_RECORD.WRITE_MDL_TOP_STOCK_DETAIL_MA(?, ?)}");
        query.setParameter(0, beginDate);
        query.setParameter(1, endDate);
        query.executeUpdate();

        session.getTransaction().commit();
        session.close();

        logger.info("按照日期【" + beginDate + "】和【" + endDate
            + "】，计算表MDL_TOP_STOCK_DETAIL中的percentage_*_ma*字段完毕");
    }

    /*********************************************************************************************************************
     *
     * 										增量备份表MDL_TOP_STOCK_DETAIL
     *
     *********************************************************************************************************************/
    /**
     * 根据开始时间beginDate和结束时间endDate，从表MDL_TOP_STOCK_DETAIL中获取DATE_字段
     * @param beginDate
     * @param endDate
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<Date> getDateByCondition(String beginDate, String endDate){
        logger.info("根据开始时间【" + beginDate + "】和结束时间【" + endDate + "】，"
            + "从表MDL_TOP_STOCK_DETAIL中获取DATE_字段");

        StringBuffer hql = new StringBuffer("select distinct t.date from ModelTopStockDetail t " +
            "where t.date between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd')");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createQuery(hql.toString());
        query.setParameter(0, beginDate);
        query.setParameter(1, endDate);
        List<Date> list = query.list();
        session.getTransaction().commit();
        session.close();

        return list;
    }

    /**
     * 从表MDL_TOP_STOCK_DETAIL中获取date日的所有ModelTopStockDetail对象
     * @param date
     * @return
     */
    @SuppressWarnings("unchecked")
    public List<ModelTopStockDetail> getModelTopStockDetailByDate(String date){
        logger.info("从表MDL_TOP_STOCK_DETAIL中获取日期【" + date + "】的所有ModelTopStockDetail对象");

        StringBuffer hql = new StringBuffer("select t from ModelTopStockDetail t " +
            "where t.date=to_date(?,'yyyy-mm-dd') order by t.date asc");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createQuery(hql.toString());
        query.setParameter(0, date);
        List<ModelTopStockDetail> list=query.list();
        session.getTransaction().commit();
        session.close();

        return list;
    }

    /**
     * 向表MDL_TOP_STOCK_DETAIL中插入ModelTopStockDetail对象
     * @param modelTopStockDetail
     */
    public void save(ModelTopStockDetail modelTopStockDetail){
        logger.info("向表MDL_TOP_STOCK_DETAIL中插入ModelTopStockDetail对象");

        session = HibernateUtil.currentSession();
        session.beginTransaction();
        session.persist(modelTopStockDetail);
        session.getTransaction().commit();
        session.close();
    }

    /**
     * 根据开始时间和结束时间，查找code，并去重
     * @param beginDate
     * @param endDate
     * @return
     */
    public List<String> findDistinctCodeBetweenDate(String beginDate, String endDate) {
        logger.info("根据开始时间【" + beginDate + "】和结束时间【" + endDate + "】，查找code，并去重");

        StringBuffer hql = new StringBuffer("select distinct t.code from ModelTopStockDetail t " +
            "where t.date between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd')");// and rownum<=10");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createQuery(hql.toString());
        query.setParameter(0, beginDate);
        query.setParameter(1, endDate);
        List<String> list = query.list();
        session.getTransaction().commit();
        session.close();

        return list;
    }

    /**
     * 查询某段时间内，up_down_percentage_21、percentage_21_ma5、percentage_21_ma10、percentage_21_ma20、close_price的平均值
     * @param beginDate
     * @param endDate
     * @return
     */
    public List<Object> findDateAndAvgBetweenGroupByOrderBy(String beginDate, String endDate) {
        logger.info("根据开始时间【" + beginDate + "】和结束时间【" + endDate + "】，查找code，并去重");

        StringBuffer hql = new StringBuffer("select t.date_, avg(t.up_down_percentage_21), avg(t.percentage_21_ma5), avg(t.percentage_21_ma10), avg(t.percentage_21_ma20), " +
                "(select avg(t1.close_price) from stock_transaction_data_all t1 where t1.date_=t.date_) " +
                "from mdl_top_stock_detail t " +
                "where t.date_ between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd') " +
                "group by t.date_ " +
                "order by t.date_ asc");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createSQLQuery(hql.toString());
        query.setParameter(0, beginDate);
        query.setParameter(1, endDate);
        List<Object> list = query.list();
        session.getTransaction().commit();
        session.close();

        return list;
    }

    /**
     * 获取某一段时间内up_down_percentage_21中的最大价格和最小价格
     * @param multithreading
     * @param beginDate
     * @param endDate
     * @return
     */
    public List getMaxMinAverageUpDownPercentage21Week(boolean multithreading, String beginDate, String endDate){

        List list;
        String queryString=new String("select max(avg(t.up_down_percentage_21)),min(avg(t.up_down_percentage_21)) from mdl_top_stock_detail t " +
                "where t.date_ between to_date(?,'yyyy-mm-dd') and to_date(?,'yyyy-mm-dd') " +
                "group by t.date_ order by t.date_ asc");

        EntityManager entityManager = null;
        javax.persistence.Query query;
        if (multithreading) {
            entityManager = JpaUtil.newEntityManager();
            entityManager.getTransaction().begin();
            query = entityManager.createNativeQuery(queryString);
        } else {
            em = JpaUtil.currentEntityManager();
            em.getTransaction().begin();
            query = em.createNativeQuery(queryString);
        }

        query.setParameter(1, beginDate);
        query.setParameter(2, endDate);
        list = query.getResultList();

        if (multithreading) {
            entityManager.getTransaction().commit();
            entityManager.close();
        } else {
            em.getTransaction().commit();
            em.close();
        }

        return list;
    }

    /**
     * 根据code，查找ModelTopStockDetail列表，并按照时间升序排列
     * @param code
     * @return
     */
    public List<ModelTopStockDetail> findByCodeOrderByDateAsc(String code){
        logger.info("根据code【" + code + "】，查找ModelTopStockDetail列表，并按照时间升序排列");

        StringBuffer hql = new StringBuffer("select t from ModelTopStockDetail t " +
            "where t.code=? order by t.date asc");
        session = HibernateUtil.currentSession();
        session.beginTransaction();
        Query query = session.createQuery(hql.toString());
        query.setParameter(0, code);
        List<ModelTopStockDetail> list = query.list();
        session.getTransaction().commit();
        session.close();

        return list;
    }
}
